#!/usr/bin/python
# -*- coding: utf-8 -*-
import os, sys,time,datetime
import paramiko
from queue import Queue
import threading,os,telnetlib,ftplib,ftputil,json

import sys
import time
 
# 普通进度条
# 在代码迭代运行中进行统计计算，并使用格式化字符串输出代码运行进度
def progress_bar():
    for i in range(1, 101): # 1-100
        print("\r", end="") # \r 表示将光标的位置回退到本行的开头位置
        print("Download progress: {} {}%".format("▋" * (i // 2), i), end="")
        sys.stdout.flush()  # sys.stdout.flush()的作用就是显示地让缓冲区的内容输出。
        time.sleep(0.02)


 
import time
from progressbar import *


event=threading.Event()
q=Queue(maxsize=150)
class SshConnectError(Exception):
    pass

class ssh_ctrl:
    def __init__(self,host,username,password,port=22):
        self.host=host
        self.ssh=ssh_ctrl.__sshConn(self.host,username,password,int(port))
        self.sftp=self.__sftpConn()

    def close(self):
        if hasattr(self.ssh,"close"):
            self.ssh.close()

    @staticmethod
    def __sshConn(host,username,password,port):
        ssh=paramiko.SSHClient()   ##创建一个SSH客户端client对象
        ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        try:
            ssh.connect(hostname=host,port=int(port),username=username,password=password)
            print("SSH %s 连接成功"%host)
        except:
            raise SshConnectError("SSH Connect %s Error!"% host)
        return ssh

    #返回sftp管道实例对象方法
    def __sftpConn(self):
        transport = self.ssh.get_transport() ##先SSH连上，再建立管道连接
        sftp=paramiko.SFTPClient.from_transport(transport) #创建一个已连通的SFTP客户端通道
        return sftp

    #执行命令方法
    def exeCommand(self,cmd,timeout=300):
        stdin,stdout,stderr=self.ssh.exec_command(cmd,timeout=timeout)
        try:
            channel=stdout.channel
            exit_code=channel.recv_exit_status()
            #报错返回127，没有报错返回0
            stdout=stdout.read().strip()
            stderr=stderr.read().strip()
            return {"status":1,"stdout":stdout,"stderr":stderr,"exit_code":exit_code}
        except:
            return {"status":0,"stdout":stdout,"stderr":stderr,"exit_code":127}


   
    def iterm_remote_path(self,abs_path):
        set_list=set()
        cmd="cd %s;./getdir.sh;cat path.txt"%abs_path
        shell_list=self.exeCommand(cmd)["stdout"].decode(encoding='utf-8').splitlines()
        # print(shell_list)
        for path in shell_list:
            # print(path)
            str_path=os.path.join(abs_path,path).replace(r'\.//','/')
            str_path=str_path.replace(r'\./','/')
            if('.' in str_path):
                set_list.add(str_path)
        # print(set_list)
        return set_list

    #文件上传下载方法
    def sftpFile(self,remotepath,localpath,action):
        try:
            if action =='push':
                # dir=os.path.split(remotepath)[0]
                dir = os.path.dirname(remotepath)
                # print(dir)
                self.exeCommand("mkdir -p %s"%dir)      #根据远程路径新建目录
                self.sftp.put(localpath,remotepath)
                return {"status":1,"message":"sftp %s %s 上传成功！"%(self.host,action),"stdout":""}
            elif action=="pull":
                self.sftp.get(remotepath,localpath)
                return {"status":1,"message":"sftp %s %s 下载成功！"%(self.host,action),"stdout":""}
        except Exception as e:
            return {"status":0,"message":"sftp %s %s 失败！%s "%(self.host,action,str(e)),"stderr":""}

'''
功能:遍历本地目录
参数:abs_path
返回:result,路径列表
'''
def iterm_local_path(abs_path):
    ##遍历本机目录，并返回
    result=set([])
    for path,dirs,files in os.walk(abs_path):
        # print(j)
        # for dir in dirs:
        #     print(dir)
        for file in files:
            file_path=os.path.join(path,file)
            result.add(file_path)
    return result


'''
功能:telnet执行远程命令
参数：
connect={
    "host":["192.168.64.131",],
    "port":"23",
    "username":"root",
    "password":"q1w2e3",
    "local_path":"",
    "remote_path":"",
    "action":"upload",
    "commands":['pwd','ps','ls','who','df -h']
}

'''
def telnet_exec(connect,**kwargs):
    # 连接服务器
    tn=telnetlib.Telnet(connect["host"],connect["port"],timeout=5)
    tn.set_debuglevel(2)

    # 输入用户名
    tn.read_until(b'login:')
    tn.write(connect["username"].encode('utf-8')+b'\n')
    # 输入密码
    tn.read_until(b'Password:')
    tn.write(connect["password"].encode('utf-8')+b'\n')
    tn.read_until(b'root@hxp-virtual-machine:~# ')
    tn.read_very_eager().decode('utf-8')
    # print(tn.read_very_eager().decode('utf-8'))

    # 登录后执行命令
    for command in connect["commands"]:
        tn.write(command.encode('utf-8')+b'\n')
        # tn.read_util(b'\r\n$')
        time.sleep(2)
        # tn.read_very_eager().decode('utf-8')
        print(tn.read_very_eager().decode('utf-8'))
    # 终止连接
    tn.close()

'''
功能:FTP 文件上传下载
参数：
connect={
    "host":"192.168.64.131",
    "port":"23",
    "username":"root",
    "password":"q1w2e3",
    "local_path":"",
    "remote_path":"",
    "action":"upload",
    "filename":"armdacu",    
}
'''
def ftp_upload(connect,**kwargs):
    ftp=FTP(connect["host"], connect["username"], connect["password"])
    ftp.encoding = 'utf-8'
    # 切换目录
    ftp.cwd(connect["remote_path"])
    # 列出文件夹内容
    ftp.retrlines('LIST')  #ftp.dir()
    if connect["action"] == "upload":
        # 删除文件

        # 上传文件
        ftp.storbinary('STOR armdacu', open('armdacu','rb').read())
        # 查看目录下详情
    elif connect["action"] =="download":
        ftp.retrbinary('RETR dacu.log', open('dacu.log','wb').write)
    for f in ftp.mlsd(path='/root'):
            print(f)

'''
功能:SSH上传音频文件
'''
def up_audio(*args, **kwargs):
    ssh=ssh_ctrl(host, username, password)
    cmd="cd %s;rm -rf audio;echo old audio has removed!"%remote_path
    ssh.exeCommand(cmd)[stdout].decode("utf8").splitlines()
    now=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
    echo_str="[{}] 文件开始上传，请耐心等待...".format(now)
    for file in iterm_local_path(local_path):
        remote=os.path.join(remote_path,os.path.basename(file))
        remote_file=remote.replace("\\", "/")
        ssh.sftpFile(remotepath=remote_file, localpath=file, action="push")
    push_number=ssh.exeCommand("cd %s;ls -l |grep '^-'|wc -l"%remote_path)["stdout"].decode('utf-8').splitlines()[0]
    print("上传%s,{}个音频文件".format(host,push_number))

'''
功能:SSH下载log文件

'''
def download(*args, **kwargs):
    ssh=ssh_ctrl(host, username, password)
    remote=os.path.dirname(remotepath)
    cmd="cd %s;tar -cvf log.tar %s"%(remote,remote)
    ssh.exeCommand(cmd)[stdout].decode("utf8").splitlines()
    localpath=remotepath.replace(remote,localpath)
    ssh.sftpFile(remotepath=remotepath, localpath=localpath, action="pull")
    echo_str="[{}] 文件开始下载，请耐心等待...".format(now)
    rm_cmd="rm -rf %s"%remotepath
    ssh.exeCommand(rm_cmd)[stdout].decode("utf8").splitlines()
    for file in ssh.iterm_remote_path(remotepath):
        print(file)
    





















# def download_file(host,username,password,remotepath,localpath):
#     x=ssh_ctrl(host,username,password)
#     remote=os.path.dirname(remotepath)
#     now1=datetime.datetime.now().strftime("%Y-%m-%d%H:%M:%S")
#     cmd="cd %s;tar -cvf log.tar %s"%(remote,remote)
#     n=x.exeCommand(cmd)["stdout"].decode(encoding='utf-8').splitlines()
#     localpath=remotepath.replace(remote,localpath)
#     a=x.sftpFile(remotepath=remotepath,localpath=localpath,action="pull")
#     now=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
#     str2="[{}] start download.{} >>> {}".format(now,remotepath,localpath)
#     # print(a,str2)
#     q.put((a,str2),block=True,timeout=None)
#     event.set()
#     b=x.exeCommand("rm -rf %s"%remotepath)["stdout"].decode(encoding='utf-8').splitlines()
#     # print(b[0])

# def upload_files(host,username,password,remotepath,localpath):
#     x=ssh_ctrl(host,username,password)
#     if q.full():
#         time.sleep(0.01)
#         pass
#     else:
#         n0=x.exeCommand("cd %s;rm -rf audio;echo old audio has removed!"%remotepath)["stdout"].decode(encoding='utf-8').splitlines()
#         now=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
#         str2="[{}] 文件开始上传，请耐心等待...".format(now)
#         # q.put((n,str2),block=True,timeout=None)  
#         # event.set()                    
#         for l in x.iter_local_path(localpath):
#             remote1=os.path.join(remotepath,os.path.basename(l))
#             remote1=remote1.replace('\\','/')
#             x.sftpFile(localpath=l,remotepath=remote1,action="push")
#         n=x.exeCommand("cd %s;ls -l |grep '^-'|wc -l"%remotepath)["stdout"].decode(encoding='utf-8').splitlines()
#         n1=host+"文件上传完成，一共上传了"+n[0]+"个音频文件。"
#         q.put((n0,str2,n1),block=True,timeout=None)
#         event.set()

# def write_config(config_dict):
#     config=configparser.ConfigParser()
#     config.read_dict(config_dict)

#     with open('./config.ini','w') as configfile:
#         config.write(configfile)

# def read_config():
#     config=configparser.ConfigParser()
#     conf=config.read('./config.ini')

#     return config



if __name__=='__main__':

# test
    paths=iterm_local_path("E:\\project\\tool\\upload\\")
    for path in paths:
        print("path:{}".format(path))

    progress_bar()

    # total = 100
    # dowork=lambda:time.sleep(0.01)
    # # widgets = ['Progress: ', Percentage(), Bar('#'),Timer(),ETA(),FileTransferSpeed()]
    # widgets = ['Progress: ', Percentage(), Bar('#'),Timer(),FileTransferSpeed()]

    # bar = ProgressBar(widgets=widgets, maxval=total)
    # bar.start()#

    # for i in range(total):
    #     bar.update(i+1)
    #     dowork()

    # bar.finish()
    import time,progressbar
    dowork=lambda:time.sleep(0.01)
    bar = progressbar.ProgressBar()
    for i in bar(range(100)):
        dowork()